package com.jkl.webserver.Web.Service;

import Minio.MinioTemplate;
import Redis.RedisCache;
import com.jkl.webserver.Web.DAO.mapper.AccountMapper;
import com.jkl.webserver.Web.DAO.mapper.RelationshipMapper;
import com.jkl.webserver.Web.DAO.pojo.*;


import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;

@Service
public class WebIndexService {
    private final AccountMapper accountMapper;
    private final RelationshipMapper relationshipMapper;
    private final RedisCache redisCache;

    private final MinioTemplate minio;
    private final static String resourceImgPath = "/Index";
    @Autowired
    public WebIndexService(AccountMapper accountMapper, RelationshipMapper relationshipMapper, RedisCache redisCache, MinioTemplate minio) {
        this.accountMapper = accountMapper;
        this.relationshipMapper = relationshipMapper;
        this.redisCache = redisCache;
        this.minio = minio;
    }
    public void downloadFile(String filepath, HttpServletResponse response) throws Exception {
        IOUtils.copy(minio.getObject(filepath),response.getOutputStream());
    }

    public String getUserName(String email) //根据账号来获取该账号的用户名
    {
        String username= redisCache.getCacheMapValue(email,"name");
        if(username==null){
            Account account=accountMapper.selectU(email);
            redisCache.setCacheMapValue(email,"name",account.getUserName());
            return account.getUserName();
        }
        return username;
    }

    public String createDynamic(String email) throws IOException {//创建动态的存储空间
        long Time= System.currentTimeMillis();//获取现在的时间(毫秒)
        hadoop.existDir("/userRes/" + email + "/userDynamic/"+email +"_"+ Time+"/evaluate");
        return email +"_"+ Time;//返回该动态的did(标识DynamicID)
    }

    public void createDynamicText(String email, String dynamicID, InputStream in) throws IOException {//保存动态的文本内容
        hadoop.copyFileToHDFS(in,"/userRes/" + email + "/userDynamic/"+dynamicID+"/theme.txt");
    }

    public ResponseEntity<Void> createDynamicImg(String email, String dynamicID, Map<String, MultipartFile> files) {//保存动态的图片
        String savePath= "/userRes/" + email + "/userDynamic/"+dynamicID+"/img";
        return upLoadFile(savePath,files);
    }

//    public List<Dynamic> getDynamics(String email){//根据账号来获取用户的所有动态
//        File dynamicDir=new File(xfile.getBasePath()+"/userRes/"+email+"//userDynamic");
//        return getDynamics(xfile.getAll(dynamicDir));
//    }
    public List<RDynamic> getDynamics(String email, String username, List<File> dirList)//根据用户动态的保存目录(即userDynamic目录)列表来获取所有动态
    {
        //以一维度的方式存储动态
        List<RDynamic> RDynamics =new ArrayList<>();
        for(File dir: dirList)//遍历userDynamic目录下的用户每个动态
        {
            RDynamic RDynamic =new RDynamic();
            String[] name=dir.getName().split("_");
            try
            {
                RDynamic.DynamicID=dir.getName();
                if(Objects.equals(email, name[0])){
                    RDynamic.uname=username;
                    RDynamic.userImg=resourceImgPath+"/img?name=get_head_img";
                }
                else{
                    RDynamic.uname= getUserName(name[0]);
                    RDynamic.userImg=resourceImgPath+"/img?name=get_head_img&&user="+name[0];
                }
                RDynamic.ptime=name[1];

                RDynamic.theme=xfile.readFile(dir+"//theme.txt");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            File imgDir=new File(dir,"img");
            List<File> fileList=xfile.getAllFileByDir(imgDir);
            for(File file:fileList){
                RDynamic.imgurl.add(resourceImgPath+"/img?name=dynamicImg&&dynamicPath="+dir.getName()+"&&imgName="+file.getName());
            }

            File evaluateDir=new File(dir,"evaluate");
            List<File> evaluationList=xfile.getAll(evaluateDir);
            Collections.sort(evaluationList, new Comparator<File>() {
                @Override
                public int compare(File f1, File f2) {
                    String[] fileName1=f1.getName().split("_");
                    String[] fileName2=f2.getName().split("_");
                    // 使用Long来避免整数溢出，并确保能处理大数字
                    long number1 = Long.parseLong(fileName1[1]);
                    long number2 = Long.parseLong(fileName2[1]);
                    // 为了实现由大到小排序，返回 number2 - number1 的结果
                    return Long.compare(number1, number2);
                }
            });
            for(File file:evaluationList)
            {
                //System.out.println(file.getName());
                String commentID=file.getName();
                String[] ename=commentID.split("_");
                REvaluation REvaluation =new REvaluation();
                try {
                    REvaluation.commentID=commentID;
                    if(Objects.equals(email, ename[0])){
                        REvaluation.userImg=resourceImgPath+"/img?name=get_head_img";
                        REvaluation.userName=username;
                    }
                    else{
                        REvaluation.userImg=resourceImgPath+"/img?name=get_head_img&&user="+ename[0];
                        REvaluation.userName=getUserName(ename[0]);
                    }
                    REvaluation.ctime=ename[1];
                    REvaluation.content=xfile.readFile(file+"//evaluate.txt");
                    File eimgDir=new File(file,"img");
                    List<File> imgList=xfile.getAllFileByDir(eimgDir);
                    for(File img:imgList)
                    {
                        REvaluation.imgurl.add(resourceImgPath+"/img?name=commentImg&&dynamicPath="+dir.getName()+"&&commentPath="+commentID+"&&imgName="+img.getName());
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                RDynamic.REvaluations.add(REvaluation);
            }
            RDynamics.add(RDynamic);
        }
        return RDynamics;
    }
    public List<RDynamic> getSortDynamicsByTime(String email, String username){//将动态以时间顺序进行排序(小为优先)
        //获取一个用户的所有好友
        List<Relationship> friends= redisCache.getCacheMapValue(email,"friends");
        if(friends==null){
            friends= relationshipMapper.selectFriends(email);
            redisCache.setCacheMapValue(email,"friends", friends);
        }

        //存储每个用户下的所有动态
        List<List<File>> TFiles=new ArrayList<>();
        //将本用户的动态添加进去
        File dynamicDir = new File(xfile.getBasePath() + "/userRes/" + email + "/userDynamic");
        List<File> dirList = xfile.getAll(dynamicDir);
        TFiles.add(dirList);
        for (Relationship friend : friends) {//将每个好友的动态添加到TFiles
            if(Objects.equals(friend.getBuildTime(), "0"))
                continue;
            dynamicDir = new File(xfile.getBasePath() + "/userRes/" + friend.getFriendId() + "/userDynamic");
            dirList = xfile.getAll(dynamicDir);
            TFiles.add(dirList);
        }

        List<File> OFiles=new ArrayList<>();
        for(int i=0;i<TFiles.size();i++)//将每行的动态按时间从大到小进行排序
        {
            TFiles.set(i,sortList(TFiles.get(i)));//将排序好的动态与原来的动态替换
        }

        int size=0;
        for (List<File> tFile : TFiles) {//计算总动态的数量
            size += tFile.size();
        }
        while(size!=0){//将二维转换成一维
            int row=minByRow(TFiles);//从每行中的第一个值进行比较,找出最大值
            OFiles.add(TFiles.get(row).get(0));
            TFiles.get(row).remove(0);
            size--;
        }
        return getDynamics(email,username,OFiles);
    }
    public List<File> sortList(List<File> files){//将每个用户的动态以时间从大到小进行排序
        for(int i=0;i<files.size();i++)
        {
            String[] name=files.get(i).getName().split("_");//以"_"来切分动态文件名
            long minnum=Long.parseLong(name[1]);//获取动态的创建的时间
            int index=i;
            for(int j=i+1;j<files.size();j++)//找出最小值
            {
                name=files.get(j).getName().split("_");
                long num=Long.parseLong(name[1]);
                if(num<minnum){
                    minnum=num;
                    index=j;
                }
            }
            Collections.swap(files,i,index);//交换最小值与位置i的值
        }
        return files;
    }
    public int minByRow( List<List<File>> TFiles){//找出二维中的每行第一个值的最小值的位置
        LocalDateTime now = LocalDateTime.now();
        ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());
        long minnum=zonedDateTime.toInstant().toEpochMilli();//获取现在的时间(毫秒)
        int index=0;
        for(int i=0;i<TFiles.size();i++)
        {
            if (TFiles.get(i).size()==0)//排除没有动态的用户
            {
                continue;
            }
            String[] name=TFiles.get(i).get(0).getName().split("_");
            long num=Long.parseLong(name[1]);
            if(num<minnum)
            {
                minnum=num;
                index=i;
            }
        }
        return index;
    }
    public RDynamic getNewDynamic(String email, String username, String DynamicID)//获取刚发出来的动态
    {
        RDynamic RDynamic =new RDynamic();
        File dynamicDir=new File(xfile.getBasePath()+"/userRes/"+email+"/userDynamic/"+DynamicID);
        String[] name=DynamicID.split("_");
        try
        {
            RDynamic.DynamicID=dynamicDir.getName();
            RDynamic.userImg=resourceImgPath+"/img?name=get_head_img";
            RDynamic.uname= username;
            RDynamic.ptime=name[1];
            RDynamic.theme=xfile.readFile(dynamicDir+"//theme.txt");

            File imgDir=new File(dynamicDir,"img");
            List<File> fileList=xfile.getAllFileByDir(imgDir);
            for(File file:fileList)
            {
                RDynamic.imgurl.add(resourceImgPath+"/img?name=dynamicImg&&dynamicPath="+dynamicDir.getName()+"&&imgName="+file.getName());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return RDynamic;
    }

    public void deleteDynamic(String dynamicID){//删除动态
        String[] dname=dynamicID.split("_");
        File dynamicDir=new File(xfile.getBasePath()+"/userRes/"+dname[0]+"/userDynamic/"+dynamicID);
        fileCreator.deleteDir(dynamicDir);
    }

    public String createComment(String email,String dynamicID){//创建评论空间
        String[] name=dynamicID.split("_");
        LocalDateTime now = LocalDateTime.now();
        ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault());
        long Time= zonedDateTime.toInstant().toEpochMilli();
        File dir = new File(xfile.getBasePath() + "/userRes/" + name[0]+ "/userDynamic/"+ dynamicID+"/evaluate",email+"_"+Time);
        fileCreator.createDir(dir);
        return dir.getName();
    }

    public void createCommentText(String dynamicID,String commentID,InputStream in) throws IOException {//保存评论文本内容
        String[] name=dynamicID.split("_");
        File dir = new File(xfile.getBasePath() + "/userRes/" + name[0]+ "/userDynamic/"+ dynamicID+"/evaluate/"+commentID);
        File evaluate=new File(dir,"evaluate.txt");
        copyFile.byteCopy(in, evaluate);//将文本内容上传
    }

    public ResponseEntity<Void> createCommentImg(String dynamicID,String commentID,Map<String, MultipartFile> files) throws IOException {//保存评论图片
        String[] name=dynamicID.split("_");
        File dir = new File(xfile.getBasePath() + "/userRes/" + name[0]+ "/userDynamic/"+ dynamicID+"/evaluate/"+commentID);
        File imgDir = new File(dir, "img");
        return upLoadFile(imgDir,files);
    }

    public REvaluation getNewComment(String username, String dynamicID, String commentID){//获取刚发出来的评论
        String[] dname=dynamicID.split("_");
        String[] ename=commentID.split("_");
        REvaluation REvaluation =new REvaluation();
        File evaluateDir=new File(xfile.getBasePath()+"/userRes/"+dname[0]+"/userDynamic/"+dynamicID+"/evaluate/"+commentID);
        try {
            REvaluation.commentID=commentID;
            REvaluation.userImg=resourceImgPath+"/img?name=get_head_img";
            REvaluation.userName= username;
            REvaluation.content=xfile.readFile(evaluateDir+"/evaluate.txt");
            REvaluation.ctime=ename[1];
            File imgDir=new File(evaluateDir,"img");
            List<File> fileList=xfile.getAllFileByDir(imgDir);
            for(File file:fileList){
                REvaluation.imgurl.add(resourceImgPath+"/img?name=commentImg&&dynamicPath="+dynamicID+"&&commentPath="+commentID+"&&imgName="+file.getName());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return REvaluation;
    }

    public void deleteComment(String dynamicID,String commentID){//删除评论
        String[] dname=dynamicID.split("_");
        hadoop.rmdir("/userRes/"+dname[0]+"/userDynamic/"+dynamicID+"/evaluate/"+commentID,"");
    }
    private ResponseEntity<Void> upLoadFile(String fileDir,Map<String, MultipartFile> files) {
        List<String> list=new ArrayList<>();
        for (Map.Entry<String, MultipartFile> entry : files.entrySet()) {
            MultipartFile file = entry.getValue();
            if (!file.isEmpty()) {
                try {
                    // 处理图片重名问题
                    UUID uuid = UUID.randomUUID();
                    String fileNamePrefix = uuid.toString().replaceAll("-", "").substring(0,7).toUpperCase();
                    //获取文件名
                    String fileName = file.getName();
                    fileName = fileNamePrefix + "_" + fileName;
                    list.add(fileName);
                    hadoop.copyFileToHDFS(file.getInputStream(),fileDir+"/"+fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                    return ResponseEntity.status(500).build();
                }
            }
        }
        //保存到数据库中

        return ResponseEntity.ok().build(); // 发送HTTP 200 OK响应
    }
}

